unit Mapper;

interface

uses
  Database,
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, StdCtrls, Buttons, Printers, Mask, Menus, JvExMask, JvSpin;

type
  TFormMapper = class(TForm)
    PanelImage: TPanel;
    Label1: TLabel;
    BtnPrint: TBitBtn;
    DialogPrint: TPrintDialog;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    Label7: TLabel;
    Bevel1: TBevel;
    Image2: TImage;
    Page: TImage;
    Label2: TLabel;
    LabelDPI: TLabel;
    Label10: TLabel;
    BtnReset: TBitBtn;
    CheckCheckerboard: TCheckBox;
    CheckDiagonal: TCheckBox;
    CheckSkew: TCheckBox;
    Label9: TLabel;
    Label11: TLabel;
    Bevel2: TBevel;
    Bevel3: TBevel;
    CheckBorder: TCheckBox;
    BtnHelp: TBitBtn;
    MainMenu1: TMainMenu;
    Main1: TMenuItem;
    MenuHelp: TMenuItem;
    BtnOK: TBitBtn;
    BtnCancel: TBitBtn;
    Label8: TLabel;
    ImageMap: TImage;
    ImageMapBase: TImage;
    LabelChanged: TLabel;
    PanelStatus: TPanel;
    Status: TLabel;
    SpinX: TJvSpinEdit;
    SpinDPI: TJvSpinEdit;
    SpinY: TJvSpinEdit;
    SpinH: TJvSpinEdit;
    SpinW: TJvSpinEdit;
    SpinD: TJvSpinEdit;
    SpinCheck: TJvSpinEdit;
    SpinDiag: TJvSpinEdit;
    SpinSkew: TJvSpinEdit;
    SpinBorder: TJvSpinEdit;
    procedure BtnOKClick(Sender: TObject);
    procedure BtnPrintClick(Sender: TObject);
    procedure SpinXChange(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure SpinDPIChange(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure BtnResetClick(Sender: TObject);
    procedure BtnHelpClick(Sender: TObject);
    procedure BtnCancelClick(Sender: TObject);
    procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
  private
    { Private declarations }
    procedure LoadOptions;
    procedure SaveOptions;
    procedure DrawCanvas(kind: string; grid: TCanvas);
  public
    { Public declarations }
  end;

var
  FormMapper: TFormMapper;
  currentDPI: integer;

implementation
uses
  Types;

{$R *.DFM}

procedure TFormMapper.FormCreate(Sender: TObject);
begin
  currentDPI:=360;
  with ImageMap.canvas do begin
    brush.color:=clbtnface;
    BrushCopy(Bounds(0,0,77,77),ImageMapBase.picture.bitmap,
      Bounds(0,0,77,77),cllime);
  end;
end;

procedure TFormMapper.FormShow(Sender: TObject);
begin
  LoadOptions;
  SpinXChange(sender);
  LabelChanged.hide;
end;

procedure TFormMapper.BtnOKClick(Sender: TObject);
begin
  SaveOptions;
  close;
end;

procedure TFormMapper.LoadOptions;
var
  i: integer;
  code: string;
begin
  code:=Datawell.TableGlobals.fieldbyname('PrinterOptions').asstring;
  i:=pos('|',code); if i < 1 then begin BtnReset.click; exit; end;
  SpinDPI.value:=strtofloat(copy(code,1,i-1)); delete(code,1,i);
  i:=pos('|',code); if i < 1 then begin BtnReset.click; exit; end;
  SpinX.value:=strtofloat(copy(code,1,i-1)); delete(code,1,i);
  i:=pos('|',code); if i < 1 then begin BtnReset.click; exit; end;
  SpinY.value:=strtofloat(copy(code,1,i-1)); delete(code,1,i);
  i:=pos('|',code); if i < 1 then begin BtnReset.click; exit; end;
  SpinH.value:=strtofloat(copy(code,1,i-1)); delete(code,1,i);
  i:=pos('|',code); if i < 1 then begin BtnReset.click; exit; end;
  SpinW.value:=strtofloat(copy(code,1,i-1)); delete(code,1,i);
  i:=pos('|',code); if i < 1 then begin BtnReset.click; exit; end;
  SpinD.value:=strtofloat(copy(code,1,i-1)); delete(code,1,i);
  i:=pos('|',code); if i < 1 then begin BtnReset.click; exit; end;
  SpinCheck.value:=strtofloat(copy(code,1,i-1)); delete(code,1,i);
  i:=pos('|',code); if i < 1 then begin BtnReset.click; exit; end;
  SpinDiag.value:=strtofloat(copy(code,1,i-1)); delete(code,1,i);
  i:=pos('|',code); if i < 1 then begin BtnReset.click; exit; end;
  SpinSkew.value:=strtofloat(copy(code,1,i-1)); delete(code,1,i);
  if pos('C',code) > 0 then CheckCheckerboard.checked:=true;
  if pos('D',code) > 0 then CheckDiagonal.checked:=true;
  if pos('S',code) > 0 then CheckSkew.checked:=true;
  if pos('B',code) > 0 then CheckBorder.checked:=true;
  LabelChanged.hide;
end;

procedure TFormMapper.SaveOptions;
var code: string;
begin
  code:='';
  code:=code+floattostr(SpinDPI.value)+'|';
  code:=code+floattostr(SpinX.value)+'|';
  code:=code+floattostr(SpinY.value)+'|';
  code:=code+floattostr(SpinH.value)+'|';
  code:=code+floattostr(SpinW.value)+'|';
  code:=code+floattostr(SpinD.value)+'|';
  code:=code+floattostr(SpinCheck.value)+'|';
  code:=code+floattostr(SpinDiag.value)+'|';
  code:=code+floattostr(SpinSkew.value)+'|';
  if CheckCheckerboard.checked then code:=code+'C';
  if CheckDiagonal.checked then code:=code+'D';
  if CheckSkew.checked then code:=code+'S';
  if CheckBorder.checked then code:=code+'B';
  Datawell.TableGlobals.edit;
  Datawell.TableGlobals.fieldbyname('PrinterOptions').asstring:=code;
  Datawell.TableGlobals.post;
end;

procedure TFormMapper.BtnResetClick(Sender: TObject);
begin
  SpinDPI.value:=360;
  SpinX.value:=0;
  SpinY.value:=0;
  SpinH.value:=42;
  SpinW.value:=32;
  SpinD.value:=75;
  CheckCheckerboard.checked:=true;
  SpinCheck.value:=1;
  CheckDiagonal.checked:=false;
  SpinDiag.value:=1;
  CheckSkew.checked:=false;
  SpinSkew.value:=1;
  CheckBorder.checked:=true;
  SpinBorder.value:=1;
end;

procedure TFormMapper.SpinDPIChange(Sender: TObject);
begin
  SpinD.value:=SpinD.value*SpinDPI.value/currentDPI;
  currentDPI:=trunc(SpinDPI.value);
  LabelDPI.caption:='Example: '+inttostr(currentDPI)+' DPI Printer';
  LabelChanged.show;
end;

procedure TFormMapper.BtnPrintClick(Sender: TObject);
var PF: System.text;
begin
  if (not CheckCheckerboard.checked) and (not CheckDiagonal.checked) and
    (not CheckSkew.checked) then begin
    messagedlg('You must choose some grid lines to print',
      mtinformation,[mbok],0);
    CheckCheckerboard.setfocus;
    exit;
  end;
  if not DialogPrint.execute then exit;
  AssignPRN(PF);
  ReWrite(PF);
  Printer.title:=Datawell.ptitle;
  with Printer.canvas do begin
    font.name:='Arial';
    font.size:=10;
    font.style:=[fsbold];
    pen.color:=clblack;
    pen.width:=2;
  end;
  DrawCanvas('print',Printer.canvas);
  CloseFile(PF);
end;

procedure TFormMapper.SpinXChange(Sender: TObject);
begin
  Page.canvas.polygon([point(0,0),point(169,0),
    point(169,219),point(0,219),point(0,0)]);
  Page.canvas.pen.color:=clblack;
  Page.canvas.pen.width:=1;
  DrawCanvas('display',Page.canvas);
  LabelChanged.show;
end;

procedure TFormMapper.DrawCanvas(kind: string; grid: TCanvas);
var
  x, y, x1, y1, x2, y2, i, h, w, d: integer;
begin
  if kind = 'display' then begin
    x:=trunc(SpinX.value)+3;
    y:=trunc(SpinY.value)+3;
    d:=trunc(SpinD.value*24/SpinDPI.value);
  end
  else begin
    x:=trunc(SpinX.value*SpinDPI.value/24)+5;
    y:=trunc(SpinY.value*SpinDPI.value/24)+5;
    d:=trunc(SpinD.value);
  end;
  h:=trunc(SpinH.value);
  w:=trunc(SpinW.value);
  //Border
  if CheckBorder.checked then begin
    if kind = 'print' then begin
      case trunc(SpinBorder.value) of
        1: grid.pen.width:=trunc(SpinDPI.value/360);
        2: grid.pen.width:=trunc(SpinDPI.value/120);
        3: grid.pen.width:=trunc(SpinDPI.value/72);
      end;
    end
    else grid.pen.width:=trunc(SpinBorder.value);
    grid.polygon([point(x,y),point(w*d+x,y)]);
    grid.polygon([point(w*d+x,y),point(w*d+x,h*d+y)]);
    grid.polygon([point(w*d+x,h*d+y),point(x,h*d+y)]);
    grid.polygon([point(x,h*d+y),point(x,y)]);
  end;
  if CheckCheckerboard.checked then begin
    if kind = 'print' then begin
      case trunc(SpinCheck.value) of
        1: grid.pen.width:=trunc(SpinDPI.value/360);
        2: grid.pen.width:=trunc(SpinDPI.value/120);
        3: grid.pen.width:=trunc(SpinDPI.value/72);
      end;
    end
    else grid.pen.width:=trunc(SpinCheck.value);
    //Horizontal lines
    for i:=1 to h-1 do
      grid.polygon([point(x,d*i+y),point(w*d+x,d*i+y)]);
    //Vertical lines
    for i:=1 to w-1 do
      grid.polygon([point(d*i+x,y),point(d*i+x,h*d+y)]);
  end;
  if CheckDiagonal.checked then begin
    if kind = 'print' then begin
      case trunc(SpinDiag.value) of
        1: grid.pen.width:=trunc(SpinDPI.value/360);
        2: grid.pen.width:=trunc(SpinDPI.value/120);
        3: grid.pen.width:=trunc(SpinDPI.value/72);
      end;
    end
    else grid.pen.width:=trunc(SpinDiag.value);
    //RLines: Top
    for i:=0 to w do begin
      x1:=d*i;
      x2:=w*d;
      y1:=0;
      y2:=w*d-x1;
      if y2 > h*d then begin
        x2:=w*d-y2+h*d;
        y2:=h*d;
      end;
      grid.polygon([point(x1+x,y1+y),point(x2+x,y2+y)]);
    end;
    //RLines: Left
    for i:=0 to h do begin
      x1:=0;
      x2:=w*d;
      y1:=d*i;
      y2:=y1+w*d;
      if y2 > h*d then begin
        x2:=w*d-y2+h*d;
        y2:=h*d;
      end;
      grid.polygon([point(x1+x,y1+y),point(x2+x,y2+y)]);
    end;
    //LLines: Left
    for i:=0 to h do begin
      x1:=w*d;
      x2:=0;
      y1:=d*i;
      y2:=y1+w*d;
      if y2 > h*d then begin
        x2:=y2-h*d;
        y2:=h*d;
      end;
      grid.polygon([point(x1+x,y1+y),point(x2+x,y2+y)]);
    end;
    //LLines: Top
    for i:=0 to w do begin
      x1:=w*d-d*i;
      x2:=0;
      y1:=0;
      y2:=x1;
      if y2 > h*d then begin
        x2:=y2-h*d;
        y2:=h*d;
      end;
      grid.polygon([point(x1+x,y1+y),point(x2+x,y2+y)]);
    end;
  end;
  if CheckSkew.checked then begin
    if kind = 'print' then begin
      case trunc(SpinSkew.value) of
        1: grid.pen.width:=trunc(SpinDPI.value/360);
        2: grid.pen.width:=trunc(SpinDPI.value/120);
        3: grid.pen.width:=trunc(SpinDPI.value/72);
      end;
    end
    else grid.pen.width:=trunc(SpinSkew.value);
    //RLines: Top
    for i:=0 to trunc(w/2) do begin
      x1:=d*i*2;
      x2:=w*d;
      y1:=0;
      y2:=trunc((w*d-x1)/2);
      if y2 > h*d then begin
        x2:=w*d-(y2-h*d)*2;
        y2:=h*d;
      end;
      grid.polygon([point(x1+x,y1+y),point(x2+x,y2+y)]);
    end;
    //RLines: Left
    for i:=0 to h do begin
      x1:=0;
      x2:=w*d;
      y1:=d*i;
      y2:=y1+trunc(w*d/2);
      if y2 > h*d then begin
        x2:=w*d-(y2-h*d)*2;
        y2:=h*d;
      end;
      grid.polygon([point(x1+x,y1+y),point(x2+x,y2+y)]);
    end;
    //LLines: Left
    for i:=0 to h do begin
      x1:=w*d;
      x2:=0;
      y1:=d*i;
      y2:=y1+trunc(w*d/2);
      if y2 > h*d then begin
        x2:=(y2-h*d)*2;
        y2:=h*d;
      end;
      grid.polygon([point(x1+x,y1+y),point(x2+x,y2+y)]);
    end;
    //LLines: Top
    for i:=0 to trunc(w/2) do begin
      x1:=w*d-d*i*2;
      x2:=0;
      y1:=0;
      y2:=trunc(x1/2);
      if y2 > h*d then begin
        x2:=(y2-h*d)*2;
        y2:=h*d;
      end;
      grid.polygon([point(x1+x,y1+y),point(x2+x,y2+y)]);
    end;
  end;
end;

procedure TFormMapper.BtnHelpClick(Sender: TObject);
begin
  Datawell.Help('print_graph_paper');
end;

procedure TFormMapper.BtnCancelClick(Sender: TObject);
begin
  close;
end;

procedure TFormMapper.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  Status.caption:=' '+(sender as TControl).hint;
end;

end.
